package cpa.prowon.gui;

import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;

import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;

import pho.prowon.category.IndexCategoryDefinition;
import pho.prowon.category.IndexCategoryDefinitionFactory;
import pho.prowon.category.RootIndexCategory;
import cpa.prowon.Application;
import cpa.prowon.gui.actions.ClearIndexAction;
import cpa.prowon.gui.actions.ExportAllToFolderAction;
import cpa.prowon.gui.actions.ExportToFolderAction;
import cpa.prowon.gui.actions.ImportFromFolderAction;
import cpa.prowon.gui.actions.ImportSingleImagesAction;
import cpa.prowon.gui.actions.RemoveCategoryAction;
import cpa.prowon.gui.actions.RenameCategoryAction;
import cpa.prowon.gui.actions.SaveIndexAction;
import cpa.prowon.gui.actions.SelectCategorizationAction;
import cpa.prowon.image.ImageContainer;

/**
 * Represents the category viewer
 * @author Chris
 */
public class WindowCategoryPart extends WindowPart {

	private TreeViewer treeViewer;
	private RemoveCategoryAction actionRemoveCategory;
	private RenameCategoryAction actionRenameCategory;
	private RootIndexCategory rootIndexCategory;
	private ExportAllToFolderAction actionExportAllToFolder;
	private ExportToFolderAction actionExportToFolder;
	private ImportFromFolderAction actionImportFromFolder;
	private ImportSingleImagesAction actionImportSingleImages;
	private SaveIndexAction actionSaveIndex;
	private ClearIndexAction actionClearIndex;

	/**
	 * This class handles key strokes
	 * @author Chris
	 */
	private class TreeViewKeyAdapter extends KeyAdapter
	{
		public void keyPressed(KeyEvent e)
		{
			if (e.character == SWT.DEL)
			{
				actionRemoveCategory.run();
			}
			if (e.character == SWT.LF)
			{
				actionRenameCategory.run();
			}
		}
	}
	
	/**
	 * This class handles double clicks
	 * @author Chris
	 */
	private class TreeViewDoubleClickListener implements IDoubleClickListener
	{
		public void doubleClick(DoubleClickEvent event)
		{
			actionRenameCategory.run();
		}
	}

	/**
	 * Constructor
	 * @param MainWindow The main window
	 * @author Chris
	 */
	public WindowCategoryPart(MainWindow aMainWindow) {
		super(aMainWindow);
	}

	/* (non-Javadoc)
	 * @see cpa.prowon.gui.WindowPart#getTitle()
	 */
	protected String getTitle() {
		return Application.getInstance().getResourceBundle().getString("title_categories");
	}

	/* (non-Javadoc)
	 * @see cpa.prowon.gui.WindowPart#getIcon()
	 */
	protected String getIcon() {
		return "icons/filenav.gif";
	}

	/**
	 * Create the actions for this window part
	 * @author Chris
	 */
	protected void createActions()
	{
		actionRemoveCategory = new RemoveCategoryAction(getMainWindow());
		actionRenameCategory = new RenameCategoryAction(getMainWindow());
		actionSaveIndex = new SaveIndexAction(getMainWindow());
		actionExportAllToFolder = new ExportAllToFolderAction(getMainWindow());
		actionExportToFolder = new ExportToFolderAction(getMainWindow());
		actionImportFromFolder = new ImportFromFolderAction(getMainWindow());
		actionImportSingleImages = new ImportSingleImagesAction(getMainWindow());
		actionClearIndex = new ClearIndexAction(getMainWindow());
	}
	
	/* (non-Javadoc)
	 * @see cpa.prowon.gui.WindowPart#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected void createContents(Composite parent) {

		// Create the tree viewer
		treeViewer = new TreeViewer(parent, SWT.SINGLE);
		treeViewer.setContentProvider(new CategorizationTreeContentProvider());
		treeViewer.setLabelProvider(new CategorizationTreeLabelProvider());

		// Register the key listeners
		treeViewer.getTree().addKeyListener(new TreeViewKeyAdapter());

		// Add a double click listener to the tree view
		treeViewer.addDoubleClickListener(new TreeViewDoubleClickListener());
		
		// Add the context menu to the categorization viewer
		MenuManager menu_manager = new MenuManager();
		treeViewer.getTree().setMenu(menu_manager.createContextMenu(treeViewer.getTree()));
		menu_manager.add(actionRemoveCategory);
		menu_manager.add(actionRenameCategory);
		menu_manager.add(new Separator());
		menu_manager.add(actionExportToFolder);
		menu_manager.add(new Separator());
		
		// Register the appropriate actions to the categorization viewer
		treeViewer.addSelectionChangedListener(actionRemoveCategory);
		treeViewer.addSelectionChangedListener(actionRenameCategory);
		treeViewer.addSelectionChangedListener(actionExportToFolder);
		
	}
	
	/**
	 * Return the tree viewer
	 * @return The tree viewer widget
	 * @author Chris
	 */
	public TreeViewer getTreeViewer()
	{
		return treeViewer;
	}
	
	/**
	 * Set the input for the tree viewer
	 * @param String The name of the index category definition
	 * @author Chris
	 */
	public void setViewerInput(IndexCategoryDefinition cd)
	{
		
		// Set the category definition for the root index category
		if (rootIndexCategory == null) {
			rootIndexCategory = new RootIndexCategory(cd, ImageContainer.class);
		} else {
			rootIndexCategory.recategorize(cd);
		}
		
		// Set the input for the viewer
		getTreeViewer().setInput(rootIndexCategory);

		// Set the input for the picture list viewer
		getMainWindow().refreshListPart();
				
		// Remember the settings for the next time
		String propName;
		String propName2;
		String propValue;
		if (cd.getNameProperty().equals("")) {
			propName = Application.PROPNAME_INDEXCATEGORYDEFINITION_NAME;
			propName2 = Application.PROPNAME_INDEXCATEGORYDEFINITION_NAMEPROPERTY;
			propValue = cd.getName();
		} else {
			propName = Application.PROPNAME_INDEXCATEGORYDEFINITION_NAMEPROPERTY;;
			propName2 = Application.PROPNAME_INDEXCATEGORYDEFINITION_NAME;
			propValue = cd.getNameProperty();
		}
		Properties appProps = Application.getInstance().getApplicationProperties(); 
		appProps.setProperty(propName, propValue);
		appProps.setProperty(propName2, "");

		// Set the shell title
		String shell_title = Application.getInstance().getInternalProperties().getProperty(Application.PROPNAME_APPLICATION_NAME) + " " + Application.getInstance().getInternalProperties().getProperty(Application.PROPNAME_APPLICATION_VERSION);
		shell_title += " - " + cd.getName(); 
		getMainWindow().getShell().setText(shell_title);
		
		// Set the appropriate action selected
		SelectCategorizationAction.setChecked(cd);
		
	}
	
	/**
	 * Return the root index category
	 * @return IndexCategory The root index category
	 * @author Chris
	 */
	public RootIndexCategory getRootIndexCategory()
	{
		return rootIndexCategory;
	}
	
	/**
	 * Return the selection of the viewer
	 * @return The selected category in the viewer
	 * @author Chris
	 */
	public IStructuredSelection getSelection()
	{
		return (IStructuredSelection) (getTreeViewer().getSelection());
	}
	
	/**
	 * Register the file menu actions
	 * @param MenuManager The menu manager to put the actions in
	 * @author Chris
	 */
	public void registerFileMenuActions(MenuManager menuMgr)
	{
		menuMgr.add(actionClearIndex);
		menuMgr.add(new Separator());
		menuMgr.add(actionSaveIndex);
		menuMgr.add(new Separator());
		menuMgr.add(actionImportSingleImages);
		menuMgr.add(actionImportFromFolder);
		menuMgr.add(new Separator());
		menuMgr.add(actionExportAllToFolder);
		menuMgr.add(actionExportToFolder);
	}

	/**
	 * Register the edit menu actions
	 * @param MenuManager The menu manager to put the actions in
	 * @author Chris
	 */
	public void registerEditMenuActions(MenuManager menuMgr)
	{
		menuMgr.add(new Separator());
		menuMgr.add(actionRemoveCategory);
		menuMgr.add(actionRenameCategory);
	}

	/**
	 * Register the view menu actions
	 * @param MenuManager The menu manager to put the actions in
	 * @author Chris
	 */
	public void registerViewMenuActions(MenuManager menuMgr)
	{
		Collection ic_list = IndexCategoryDefinitionFactory.getInstance().availableDefinitions();
		if (!ic_list.isEmpty()) {
			Iterator ic_list_it = ic_list.iterator();
			while(ic_list_it.hasNext()) {
				IndexCategoryDefinition icd = (IndexCategoryDefinition) ic_list_it.next();
				SelectCategorizationAction action = SelectCategorizationAction.createAction(getMainWindow(), icd);
				menuMgr.add(action);
			}
		}
	}

	/**
	 * Register the toolbar actions
	 * @param ToolBarManager The tool bar manager to put the actions in
	 * @author Chris
	 */
	public void registerToolBarActions(ToolBarManager toolBarMgr)
	{
		toolBarMgr.add(actionSaveIndex);
		toolBarMgr.add(new Separator());
		toolBarMgr.add(actionImportSingleImages);
		toolBarMgr.add(actionImportFromFolder);
	}

}
